import sqlite3
import os
from typing import Optional, Dict, Any


class DbManager:
    """
    SQLite数据库管理类，使用主连接(写)和只读连接模式
    """
    # 数据库文件路径固定为data.db
    DB_PATH = "data.db"
    _main_conn = None  # 主连接用于写操作
    _is_initialized = False
    
    @staticmethod
    def _create_main_connection() -> sqlite3.Connection:
        """
        创建主数据库连接并配置
        
        Returns:
            sqlite3.Connection: 配置好的数据库连接
        """
        conn = sqlite3.connect(DbManager.DB_PATH, check_same_thread=False)
        # 设置row_factory以支持字典式访问
        conn.row_factory = sqlite3.Row
        # 启用外键约束
        conn.execute("PRAGMA foreign_keys = ON")
        # 启用WAL模式，提高并发性能
        conn.execute("PRAGMA journal_mode = WAL")
        return conn
        
    @staticmethod
    def initialize() -> bool:
        """
        初始化数据库
        
        Returns:
            bool: 初始化是否成功
        """
        try:
            # 确保数据库目录存在
            db_dir = os.path.dirname(DbManager.DB_PATH)
            if db_dir and not os.path.exists(db_dir):
                os.makedirs(db_dir)
            
            # 检查数据库文件是否存在
            db_exists = os.path.exists(DbManager.DB_PATH)
                
            # 创建主连接
            DbManager._main_conn = DbManager._create_main_connection()
                
            DbManager._is_initialized = True
            
            # 如果数据库文件不存在，需要创建表
            # if not db_exists:
            #     return
            DbManager.initialize_tables()
            return True
        except Exception as e:
            print(f"初始化数据库失败: {e}")
            return False
    
    @staticmethod
    def get_conn(for_writing: bool = False) -> Optional[sqlite3.Connection]:
        """
        获取数据库连接
        
        Args:
            for_writing: 是否用于写操作
            
        Returns:
            sqlite3.Connection: 数据库连接对象，获取失败返回None
        """
        if not DbManager._is_initialized:
            if not DbManager.initialize():
                return None
        
        try:
            if for_writing:
                # 返回主连接用于写操作
                return DbManager._main_conn
            else:
                # 创建新的只读连接
                conn = sqlite3.connect(f'file:{DbManager.DB_PATH}?mode=ro', uri=True)
                conn.row_factory = sqlite3.Row
                return conn
        except Exception as e:
            print(f"获取数据库连接时出错: {e}")
            return None
    
    @staticmethod
    def release_connection(conn: sqlite3.Connection) -> None:
        """
        释放数据库连接
        
        Args:
            conn: 要释放的数据库连接
        """
        # 只关闭只读连接，主连接由DbManager管理
        if conn and conn != DbManager._main_conn:
            try:
                conn.close()
            except Exception as e:
                print(f"关闭数据库连接时出错: {e}")
    
    @staticmethod
    def create_table(table_name: str, columns_definition: str) -> bool:
        """
        创建数据表
        
        Args:
            table_name: 表名
            columns_definition: 列定义字符串
            
        Returns:
            bool: 是否创建成功
        """
        create_table_sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({columns_definition})"
        
        conn = DbManager.get_conn(for_writing=True)
        if not conn:
            return False
            
        try:
            cursor = conn.cursor()
            cursor.execute(create_table_sql)
            conn.commit()
            return True
        except Exception as e:
            conn.rollback()
            print(f"创建表 {table_name} 失败: {e}")
            return False
    
    @staticmethod
    def initialize_tables() -> bool:
        """
        初始化所有数据表
        
        Returns:
            bool: 所有表是否创建成功
        """
        # 定义要创建的表
        tables = [
            {
                "name": "user_info",
                "definition": """
                    	id INTEGER PRIMARY KEY AUTOINCREMENT,
                        user TEXT NOT NULL UNIQUE,
                        pass TEXT,
                        user_id TEXT,
                        token TEXT,--token
                        level TEXT,--等级
                        name TEXT,--姓名
                        mail TEXT,--邮箱
                        mail_pass TEXT,--邮箱密码
                        card_name TEXT,--卡片名称信息
                        source_info TEXT,--资源信息
                        country TEXT,--国家
                        notes TEXT,--备注
                        upload_id TEXT,--上传自选返回的ID
                        flag INTEGER DEFAULT 0,--0 未使用 1 使用中 2 成功  3 失败  4 上传
                        account_info TEXT,--账号信息
                        create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,--创建时间
                        update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP--更新时间
                """
            },{
                "name": "mail_info",
                "definition": """
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    mail TEXT NOT NULL UNIQUE,--邮箱
                    mail_pass TEXT,--邮箱密码
                    flag INTEGER DEFAULT 0,--0 未使用 1 使用中 2 使用成功
                    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,--创建时间
                    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP--更新时间
                """
            }
        ]
        
        # 创建表
        success = True
        for table in tables:
            if not DbManager.create_table(table["name"], table["definition"]):
                success = False
                print(f"创建表 {table['name']} 失败")
                return False
                
        return success
    
    @staticmethod
    def update_user_info(user_id: int, data: dict) -> bool:
        """
        更新用户信息，自动更新时间戳
        
        Args:
            user_id: 用户ID
            data: 要更新的数据字段
            
        Returns:
            bool: 是否更新成功
        """
        if not data:
            return False
            
        # 创建新字典以避免修改原始数据
        update_data = data.copy()
        
        # 移除update_time如果存在，我们将在SQL语句中直接使用datetime('now')
        if 'update_time' in update_data:
            del update_data['update_time']
            
        # 构建SET子句，对于update_time使用datetime('now')函数
        set_clause_parts = [f"{key} = ?" for key in update_data.keys()]
        set_clause_parts.append("update_time = CURRENT_TIMESTAMP")  # 添加时间戳更新
        set_clause = ", ".join(set_clause_parts)
        values = list(update_data.values())
        
        # 构建SQL语句
        sql = f"UPDATE user_info SET {set_clause} WHERE id = ?"
        values.append(user_id)
        
        conn = DbManager.get_conn(for_writing=True)
        if not conn:
            return False

        try:
            cursor = conn.cursor()
            cursor.execute(sql, values)
            conn.commit()
            return cursor.rowcount > 0
        except Exception as e:
            conn.rollback()
            print(f"更新用户信息失败: {e}")
            return False
    
    @staticmethod
    def insert_user_info(data: dict) -> int:
        """
        插入用户信息
        
        Args:
            data: 用户数据
            
        Returns:
            int: 新插入记录的ID，失败返回0
        """
        if not data or 'user' not in data:
            return 0
            
        # 构建插入语句
        fields = ", ".join(data.keys())
        placeholders = ", ".join(["?"] * len(data))
        values = list(data.values())
        
        sql = f"INSERT INTO user_info ({fields}) VALUES ({placeholders})"
        
        conn = DbManager.get_conn(for_writing=True)
        if not conn:
            return 0
            
        try:
            cursor = conn.cursor()
            cursor.execute(sql, values)
            conn.commit()
            return cursor.lastrowid
        except Exception as e:
            conn.rollback()
            print(f"插入用户信息失败: {e}")
            return 0
    
    @staticmethod
    def close() -> None:
        """
        关闭数据库连接
        """
        # 关闭主连接
        if DbManager._main_conn:
            try:
                DbManager._main_conn.close()
                DbManager._main_conn = None
            except Exception as e:
                print(f"关闭主数据库连接时出错: {e}")
            
        DbManager._is_initialized = False


# 使用示例
if __name__ == "__main__":
    # 初始化数据库
    if DbManager.initialize():
        print("数据库初始化成功")
        
        # 获取读连接示例
        read_conn = DbManager.get_conn()
        if read_conn:
            print("成功获取读数据库连接")
            # 执行查询示例
            cursor = read_conn.cursor()
            cursor.execute("SELECT * FROM user_info LIMIT 5")
            rows = cursor.fetchall()
            for row in rows:
                print(dict(row))
            DbManager.release_connection(read_conn)
            
        # 获取写连接示例
        write_conn = DbManager.get_conn(for_writing=True)
        if write_conn:
            print("成功获取写数据库连接")
            # 执行插入示例
            try:
                cursor = write_conn.cursor()
                cursor.execute("INSERT INTO user_info (user, pass) VALUES (?, ?)", 
                              ("test_user", "password123"))
                write_conn.commit()
                print(f"插入成功，影响行数: {cursor.rowcount}")
            except Exception as e:
                write_conn.rollback()
                print(f"插入失败: {e}")
        
        # 关闭数据库
        DbManager.close()
        print("数据库已关闭")
    else:
        print("数据库初始化失败")